import codec.MessagePachEncoder;
import codec.MessagePackDecoder;
import codec.NettyMessageDecoder;
import codec.NettyMessageEncoder;
import enums.NettyConstant;
import handler.HeartHeatRespHandler;
import handler.LoginAuthRespHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.timeout.ReadTimeoutHandler;

public class NettyServer {

  public static void main(String[] args) {
    EventLoopGroup bossGroup = new NioEventLoopGroup();
    EventLoopGroup workGroup = new NioEventLoopGroup();
    ServerBootstrap bootstrap = new ServerBootstrap();
    bootstrap.group(bossGroup,workGroup)
        //SO_BACKLOG 对tcp协议listen函数中的backlog参数,用来初始化服务端可连接队列,
        //服务器在处理客户端请求是顺序的,所以同一时刻只能处理一个客户端连接,多个客户端来的时候
        //服务端将不能处理的客户端连接请求放在队列中
        .channel(NioServerSocketChannel.class)
        .childOption(ChannelOption.SO_BACKLOG,100)
        .childHandler(new ChannelInitializer<SocketChannel>() {
          @Override
          protected void initChannel(SocketChannel ch) throws Exception {
            ch.pipeline().addLast(new NettyMessageDecoder(1024 * 1024,4,4));
            ch.pipeline().addLast(new NettyMessageEncoder());
            //ch.pipeline().addLast(new ReadTimeoutHandler(50));
            ch.pipeline().addLast(new LoginAuthRespHandler());
            ch.pipeline().addLast(new HeartHeatRespHandler());
          }
        });
    try {
      ChannelFuture future = bootstrap.bind(NettyConstant.REMOTEIP,NettyConstant.PORT).sync();
      System.out.println("Netty server start OK " + NettyConstant.REMOTEIP + ":" + NettyConstant.PORT);
      future.channel().closeFuture().sync();
    } catch (InterruptedException e) {
      e.printStackTrace();
    }finally {
      bossGroup.shutdownGracefully();
      workGroup.shutdownGracefully();
    }
  }

}
